using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Media;

namespace _1942
{
    /// <summary>
    /// This is a game component that implements the Action Scene.
    /// </summary>
    public class ActionScene : GameScene
    {

        #region Variables

        // Basics
        protected Texture2D actionTexture;
        private AudioLibrary audio;
        protected SpriteBatch spriteBatch = null;

        // Game Elements
        protected Player player1;
        //protected Player player2;
        protected KamikazeManager kamikazes;
        protected MinerManager miners;
        protected HunterManager hunters;
        protected BossManager bosses;

        protected PowerUp powerSource;
        protected SimpleRumblePad rumblePad;
        protected ImageComponent background;
        protected Score scorePlayer1;
        protected Score scorePlayer2;

        // Gui Stuff
        protected Vector2 pausePosition;
        protected Vector2 gameoverPosition;
        protected Vector2 stageClearPosition;
        protected Rectangle pauseRect = new Rectangle(54,582, 255, 154);
        protected Rectangle gameoverRect = new Rectangle(709, 250, 235, 124);
        protected Rectangle stageClearRect = new Rectangle(700, 390, 255, 154);

        //Window size
        private static int windowHeight = -1;
        private static int windowWidth = -1;

        // GameState elements
        protected bool paused;
        protected bool gameOver;
        protected bool stageClear;
        protected TimeSpan elapsedTime = TimeSpan.Zero;
        protected bool twoPlayers;

        //Backgrond Image
        protected Rectangle backgroundRect;
        protected Texture2D backTexture;
        private int backPicHeight;
        private int backPicY;
        private float backgroundSpeed = 0.25f;
        private Vector2 backgroundPos = Vector2.Zero;

        //Backgrond Cloud Image
        protected Rectangle backgroundCloudRect;
        protected Texture2D backCloudTexture;
        private int backCloudPicHeight;
        private int backCloudPicY;
        private float backgroundCloudSpeed = 0.75f;
        private Vector2 backgroundCloudPos = Vector2.Zero;
        private Vector2 backgroundCloud2Pos = Vector2.Zero;
        //lvl 2 of louds
        private Vector2 backgroundCloudPosLvl2 = new Vector2(0, 0);
        private Vector2 backgroundCloud2PosLvl2 = new Vector2(0, 0);
        private float backgroundCloudSpeedLvl2 = 0.35f;

        //The projectileManger, generats bullets for enemies
        ProjectileManager projectileMangagerKamikaze;
        ProjectileManager projectileMangagerMiner;
        ProjectileManager projectileMangagerHunter;

        //The projectileManger, generats bullets for player
        ProjectileManager projectileMangagerPlayer;

        #region playerShots

        //Vectors for the different shots
        Vector2 oClock12Player = new Vector2(0, -3);

        Vector2 oClock11Player = new Vector2(-3, -3);
        Vector2 oClock1Player = new Vector2(3, -3);
        Vector2 oClock10Player = new Vector2(-3, -3);
        Vector2 oClock2Player = new Vector2(3, -3);

        Vector2 oClock9Player = new Vector2(-4, 0);
        Vector2 oClock3Player = new Vector2(4, 0);

        Vector2 oClock6Player = new Vector2(0, 3);
        Vector2 oClock4Player = new Vector2(3, 3);

        Vector2 oClock8Player = new Vector2(-3, 3);

        //Origin corrections for the shots
        Vector2 corrFront = new Vector2(10, -20);
        Vector2 corrFrontL = new Vector2(-2, -15);
        Vector2 corrFrontR = new Vector2(22, -15);
        Vector2 corrFrontLL = new Vector2(-14, -15);
        Vector2 corrFrontRR = new Vector2(34, -15);

        Vector2 corrLeft = new Vector2(-20, 5);
        Vector2 corrRight = new Vector2(30, 5);

        Vector2 corrBack = new Vector2(10, -25);
        Vector2 corrBackL = new Vector2(-2, -25);
        Vector2 corrBackR = new Vector2(22, -25);

        //Player shooting position
        Vector2 playerShootingPos = new Vector2(0, 0);
        #endregion

        #region Kamikaze shots

        //Vectors for the Kamikaze shots
        Vector2 currentShot = new Vector2(0, 0);
        Vector2 oClock12Kamikaze = new Vector2(0, -1.5f);
        Vector2 oClock10Kamikaze = new Vector2(-1.5f, -1.5f);
        Vector2 oClock2Kamikaze = new Vector2(1.5f, -1.5f);
        Vector2 oClock9Kamikaze = new Vector2(-1.5f, 0);
        Vector2 oClock3Kamikaze = new Vector2(1.5f, 0);
        Vector2 oClock6Kamikaze = new Vector2(0, 1.5f);
        Vector2 oClock4Kamikaze = new Vector2(1.5f, 1.5f);
        Vector2 oClock8Kamikaze = new Vector2(-1.5f, 1.5f);

        //Origin corrections for the shots

        //Vector for the miners mines
        Vector2 mineDirection = new Vector2(0, 0.45f);

        // boss corrections
        Vector2 bossCorr = new Vector2(85, 150);

        #endregion

        #endregion


        #region Constructors

        /// <summary>
        /// Default Constructor
        /// </summary>
        /// <param name="game">The main game object</param>
        /// <param name="theTexture">Texture with the sprite elements</param>
        /// <param name="backgroundTexture">Texture for the background</param>
        /// <param name="font">Font used in the score</param>
        public ActionScene(Game game, Texture2D theTexture,
            Texture2D backgroundTexture, SpriteFont font, Texture2D backgroundCloudTexture)
            : base(game)
        {
            //Sets the window size
            if (windowHeight == -1)
            {
                windowHeight = Game.Window.ClientBounds.Height;
                windowWidth = Game.Window.ClientBounds.Width;
            }

            actionTexture = theTexture;

            //Background variables
            backPicHeight = backgroundTexture.Height;
            backPicY = backPicHeight;
            backTexture = backgroundTexture;
            backgroundPos.Y = -backPicHeight + windowHeight;
            backgroundRect.X = 0;
            backgroundRect.Y = 0;
            backgroundRect.Width = windowWidth;
            backgroundRect.Height = backPicHeight;

            //Background Cloud variables
            backCloudPicHeight = backgroundCloudTexture.Height;
            backCloudPicY = backCloudPicHeight;
            backCloudTexture = backgroundCloudTexture;

            backgroundCloudPos.Y = -backCloudPicHeight;
            backgroundCloud2Pos.Y = -2 * backCloudPicHeight;

            backgroundCloudPosLvl2.Y = -backCloudPicHeight + (backCloudPicHeight / 5) * 4;
            backgroundCloud2PosLvl2.Y = -2 * backCloudPicHeight + (backCloudPicHeight / 5) * 4;

            backgroundCloudRect.Width = windowWidth;
            backgroundCloudRect.Height = backCloudPicHeight;

            // Get the current sprite batch
            spriteBatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));

            // Get the audio library
            audio = (AudioLibrary)Game.Services.GetService(typeof(AudioLibrary));

            // Enemies!
            kamikazes = new KamikazeManager(Game, ref actionTexture);
            Components.Add(kamikazes);

            miners = new MinerManager(Game, ref actionTexture);
            Components.Add(miners);
            
            hunters = new HunterManager(Game, ref actionTexture);
            Components.Add(hunters);
            
            bosses = new BossManager(Game, ref actionTexture);
            Components.Add(bosses);

            // player
            player1 = new Player(Game, ref actionTexture, PlayerIndex.One,
                new Rectangle(275, 414, 50, 40));
            player1.Initialize();
            Components.Add(player1);

            //The projectileManger, generats bullets
            projectileMangagerPlayer = new ProjectileManager(Game, ref actionTexture, ProjectileType.Player);
            Components.Add(projectileMangagerPlayer);

            projectileMangagerKamikaze = new ProjectileManager(Game, ref actionTexture, ProjectileType.Kamakazie);
            Components.Add(projectileMangagerKamikaze);

            projectileMangagerHunter = new ProjectileManager(Game, ref actionTexture, ProjectileType.Hunter);
            Components.Add(projectileMangagerHunter);

            projectileMangagerMiner = new ProjectileManager(Game, ref actionTexture, ProjectileType.Miner);
            Components.Add(projectileMangagerMiner);

            // Score
            scorePlayer1 = new Score(game, font, new Color(150, 26, 35));
            scorePlayer1.Position = new Vector2(10, 10);
            Components.Add(scorePlayer1);


            rumblePad = new SimpleRumblePad(game);
            Components.Add(rumblePad);

            powerSource = new PowerUp(game, ref actionTexture);
            powerSource.Initialize();
            Components.Add(powerSource);
        }


        #endregion

        #region Methods

        /// <summary>
        /// Show the action scene
        /// </summary>
        public override void Show()
        {
            MediaPlayer.Play(audio.BackMusic);
            

            // Initialize all enemy managers
            kamikazes.Initialize();
            miners.Initialize();
            hunters.Initialize();

            // Reset all projectiles in scene.
            projectileMangagerKamikaze.Reset();
            projectileMangagerMiner.Reset();
            projectileMangagerHunter.Reset();

            projectileMangagerPlayer.Reset();


            powerSource.PutinStartPosition();

            player1.Reset();


            paused = false;
            pausePosition.X = (windowWidth - pauseRect.Width) / 2;
            pausePosition.Y = (windowHeight - pauseRect.Height) / 2;

            gameOver = false;
            gameoverPosition.X = (windowWidth - gameoverRect.Width) / 2;
            gameoverPosition.Y = (windowHeight - gameoverRect.Height) / 2;

            stageClear = false;
            stageClearPosition.X = (windowWidth - stageClearRect.Width) / 2;
            stageClearPosition.Y = (windowHeight - stageClearRect.Height) / 2;

            // Is a two-player game?
            player1.Visible = true;

            base.Show();
        }

        /// <summary>
        /// Hide the scene
        /// </summary>
        public override void Hide()
        {
            // Stop the background music
            MediaPlayer.Stop();
            // Stop the rumble
            rumblePad.Stop(PlayerIndex.One);
            base.Hide();
        }


        /// <summary>
        /// Handle power-up stuff
        /// </summary>
        private void HandlePowerSourceSprite(GameTime gameTime)
        {
            // Player 1 get the power source
            if (powerSource.getRect.Intersects(player1.getRect()))
            {
                //audio.PowerGet.Play();
                elapsedTime = TimeSpan.Zero;
                powerSource.PutinStartPosition();
                player1.Power++;
                player1.powerUp++;
            }


            powerSource.Enabled = true;
            // Check for send a new Power source
            elapsedTime += gameTime.ElapsedGameTime;
            /*
            if (elapsedTime > TimeSpan.FromSeconds(15))
            {
                elapsedTime -= TimeSpan.FromSeconds(15);
                powerSource.Enabled = true;
                //audio.PowerShow.Play();
            }*/
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            if ((!paused) && (!gameOver) && (!stageClear))
            {
                #region background

                //Move the background
                if (backgroundPos.Y < 0)
                {
                    backgroundPos.Y += backgroundSpeed;
                    //Move the background Cloud
                    backgroundCloudPos.Y += backgroundCloudSpeed;
                    backgroundCloud2Pos.Y += backgroundCloudSpeed;

                    backgroundCloudPosLvl2.Y += backgroundCloudSpeedLvl2;
                    backgroundCloud2PosLvl2.Y += backgroundCloudSpeedLvl2;
                }
                else
                {
                    if (bosses.AllBosses.Count < 1)
                        bosses.addBoss();
                }

                if (backgroundPos.Y > -250)
                {
                    hunters.ShouldSpawn = false;
                    miners.ShouldSpawn = false;
                    kamikazes.ShouldSpawn = false;
                }

                //Scrolls the clouds
                if (backgroundCloud2Pos.Y == 0)
                {
                    backgroundCloudPos.Y = -backCloudPicHeight;
                }
                if (backgroundCloudPos.Y == 0)
                {
                    backgroundCloud2Pos.Y = -backCloudPicHeight;
                }
                if (backgroundCloud2PosLvl2.Y == 0)
                {
                    backgroundCloudPosLvl2.Y = -backCloudPicHeight;
                }
                if (backgroundCloudPosLvl2.Y == 0)
                {
                    backgroundCloud2PosLvl2.Y = -backCloudPicHeight;
                }

                if (backgroundRect.Y < 0) backgroundRect.Y = 0;

                #endregion

                #region shooting
                /*
                * PLAYER SHOOTING
                */

                if (player1.IsShooting)
                {
                    PlayerShooting(player1.GetPos());
                }
                #endregion

               
                /*
                 * COLLISION
                 */
                //Checks collision between proj and planes and let the enemy planes shoot
                checkColAndShoot(projectileMangagerPlayer.AllProjectiles, kamikazes.AllKamikaze, miners.AllMiners, hunters.AllHunters);

                
                //Checks collision between proj and player
                if (projectileMangagerKamikaze.AllProjectiles.Count > 0) 
                    checkCol(projectileMangagerKamikaze.AllProjectiles, player1.getRect(), ProjectileType.Kamakazie);

                if (projectileMangagerKamikaze.AllProjectiles.Count > 0) 
                    checkCol(projectileMangagerHunter.AllProjectiles, player1.getRect(), ProjectileType.Hunter);

                if (projectileMangagerKamikaze.AllProjectiles.Count > 0) 
                    checkCol(projectileMangagerMiner.AllProjectiles, player1.getRect(), ProjectileType.Miner);

                

                // Check if a player get a power boost
                HandlePowerSourceSprite(gameTime);


                // Update score
               // scorePlayer1.Value = player1.Score;
                scorePlayer1.Power = player1.Power;

                
                // Check if player is dead
                gameOver = ((player1.Power <= 0));
                if (gameOver)
                {
                    player1.Visible = (player1.Power > 0);

                    // Stop the music
                    MediaPlayer.Stop();
                    // Stop rumble
                    rumblePad.Stop(PlayerIndex.One);

                }

                //Check if the player has won
                stageClear = bosses.isDefeated();

                // Update all other game components
                base.Update(gameTime);
            }

            // In game over state, keep the kamikazes animation
            if (gameOver)
            {
                kamikazes.Update(gameTime);
                projectileMangagerKamikaze.Update(gameTime);
                projectileMangagerPlayer.Update(gameTime);
            }
        }


        /// <summary>
        /// Determines how many shots PLAYER can shoot, and adds them to Players projectile list
        /// </summary>
        /// <param name="pos"></param>
        private void PlayerShooting(Vector2 pos)
        {
            audio.PlayerShoots.Play();
            //checks how many shots should be fired
            if (player1.powerUp >= 6)
            {
                projectileMangagerPlayer.AddNewProjectile(pos + corrBackL, oClock6Player, ProjectileType.Player);
                projectileMangagerPlayer.AddNewProjectile(pos + corrBackR, oClock6Player, ProjectileType.Player);
            }


            if (player1.powerUp >= 5)
            {
                projectileMangagerPlayer.AddNewProjectile(pos + corrBack, oClock4Player, ProjectileType.Player);
                projectileMangagerPlayer.AddNewProjectile(pos + corrBack, oClock8Player, ProjectileType.Player);
                projectileMangagerPlayer.AddNewProjectile(pos + corrBack, oClock6Player, ProjectileType.Player);

            }

            if (player1.powerUp >= 4)
            {
                projectileMangagerPlayer.AddNewProjectile(pos + corrFront, oClock9Player, ProjectileType.Player);
                projectileMangagerPlayer.AddNewProjectile(pos + corrFront, oClock3Player, ProjectileType.Player);
                projectileMangagerPlayer.AddNewProjectile(pos + corrFrontLL, oClock12Player, ProjectileType.Player);
                projectileMangagerPlayer.AddNewProjectile(pos + corrFrontRR, oClock12Player, ProjectileType.Player);
            }

            if (player1.powerUp >= 3)
            {
                projectileMangagerPlayer.AddNewProjectile(pos + corrFrontL, oClock12Player, ProjectileType.Player);
                projectileMangagerPlayer.AddNewProjectile(pos + corrFrontR, oClock12Player, ProjectileType.Player);
            }

            if (player1.powerUp >= 2)
            {
                projectileMangagerPlayer.AddNewProjectile(pos + corrFrontL, oClock10Player, ProjectileType.Player);
                projectileMangagerPlayer.AddNewProjectile(pos + corrFrontR, oClock2Player, ProjectileType.Player);
            }

            if (player1.powerUp == 1)
            {
                projectileMangagerPlayer.AddNewProjectile(pos + corrFrontL, oClock12Player, ProjectileType.Player);
                projectileMangagerPlayer.AddNewProjectile(pos + corrFrontR, oClock12Player, ProjectileType.Player);
            }
            else
            {
                projectileMangagerPlayer.AddNewProjectile(pos + corrFront, oClock12Player, ProjectileType.Player);
            }
        }

        /// <summary>
        /// Lets every enemyplane shoot against player
        /// </summary>
        private void kamikazeShoot(List<Kamikaze> planeList, Vector2 playPos)
        {
            Vector2 currentShot = Vector2.Zero;

            foreach (Kamikaze item in planeList)
            {
                if (item.CanShoot && item.Enabled)
                {
                    item.CanShoot = false;

                    Vector2 tempK = item.Position;

                    //Checks in player are to right or left of plane
                    if (tempK.X < playPos.X)
                    {
                        if (tempK.Y < playPos.Y)
                            currentShot = oClock4Kamikaze;
                        else
                            currentShot = oClock2Kamikaze;
                    }
                    else
                    {
                        if (tempK.Y < playPos.Y)
                            currentShot = oClock8Kamikaze;
                        else
                            currentShot = oClock10Kamikaze;
                    }

                    projectileMangagerKamikaze.AddNewProjectile(tempK, currentShot, ProjectileType.Kamakazie);
                }
            }
        }

        #region collision methods
        /// <summary>
        /// Checks Collision between players projectiles and kamikazes
        /// </summary>
        private void checkColAndShoot(List<Projectile> projList, List<Kamikaze> planeList,
                                      List<Miner> mineList, List<Hunter> hunterList)
        {
            bool firstTimeKamikaze = true;
            bool firstTimeMiner = true;
            bool firstTimeHunter = true;
            bool firstTimeBoss = true;

            // CHECK ALL PROJECTILES:::
            foreach (Projectile bullit in projList)
            {
                if (!bullit.Enabled)
                    continue;

                #region kamikaze
                foreach (Kamikaze plane in planeList)
                {
                    // if plane is not enabled
                    // if plane is exploding
                    // TRUE =  skip collision detection for that item.
                    if (!plane.Enabled || plane.Exploding || !plane.Visible)
                        continue;

                    if (bullit.getRect.Intersects(plane.getRect))
                    {
                        if (Collision.IntersectPixels(bullit.getRect, bullit.TextureData, plane.getRect, kamikazes.TextureData))
                        {
                            //if collision remove projectile and plane
                            plane.hit();
                            bullit.kill();
                            //add score
                            scorePlayer1.Value++;
                        }
                    }

                    if (firstTimeKamikaze)
                    {
                        #region collision plane player
                        if (plane.getRect.Intersects(player1.getRect()))
                        {
                            //if collision remove plane and decrease player power
                            // Shake!
                            rumblePad.RumblePad(PlayerIndex.One, 500, 1.0f, 1.0f);
                            // Player penalty
                            if (!player1.godMode)
                            {
                                player1.Power--;
                                player1.powerUp = 0;
                                player1.Score -= 10;
                            }
                            plane.kill();
                        }
                        #endregion


                        #region shooting
                        if (plane.CanShoot)
                        {
                            plane.CanShoot = false;
                            Vector2 tempK = plane.Position;
                            Vector2 tempP = player1.GetPos();

                            //Checks in player are to right or left of plane
                            if (tempK.X < tempP.X)
                            {
                                currentShot = (tempK.Y < tempP.Y) ? oClock4Kamikaze : oClock2Kamikaze;
                            }
                            else
                            {
                                currentShot = (tempK.Y < tempP.Y) ? oClock8Kamikaze : oClock10Kamikaze;
                            }
                            audio.KamikazeShoots.Play();
                            projectileMangagerKamikaze.AddNewProjectile(tempK, currentShot, ProjectileType.Kamakazie);
                        }
                        #endregion
                    }
                }

                firstTimeKamikaze = false;

                #endregion

                #region Miner

                foreach (Miner plane in mineList)
                {
                    // if plane is not enabled
                    // if plane is exploding
                    // TRUE =  skip collision detection for that item.
                    if (!plane.Enabled || plane.Exploding || !plane.Visible)
                        continue;

                    if (bullit.getRect.Intersects(plane.getRect))
                    {
                        if (Collision.IntersectPixels(bullit.getRect, player1.TextureData, plane.getRect, miners.TextureData))
                        {
                            //if collision remove projectile and plane
                            plane.hit();
                            //add score
                            scorePlayer1.Value++;
                            bullit.kill();
                            break;
                        }
                    }
                    else if (firstTimeMiner)
                    {
                        // collision plane player           
                        if (plane.getRect.Intersects(player1.getRect()))
                        {
                            //if collision remove plane and decrease player power
                            // Shake!
                            rumblePad.RumblePad(PlayerIndex.One, 500, 1.0f, 1.0f);
                            // Player penalty
                            if (!player1.godMode)
                            {
                                player1.Power--;
                                player1.powerUp = 0;
                                player1.Score -= 10;
                            }
                            plane.kill();
                        }

                        // lets the plane shoot                                
                        if (plane.CanShoot)
                        {
                            plane.CanShoot = false;
                            audio.MinerShoots.Play();
                            projectileMangagerMiner.AddNewProjectile(plane.Position, mineDirection, ProjectileType.Miner);
                        }
                    }

                }

                firstTimeMiner = false;

                #endregion

                #region Hunter
                foreach (Hunter plane in hunterList)
                {
                    // if plane is not enabled
                    // if plane is exploding
                    // TRUE =  skip collision detection for that item.
                    if (!plane.Enabled || plane.Exploding || !plane.Visible)
                        continue;

                    // collision proj plane
                    if (bullit.getRect.Intersects(plane.getRect))
                    {
                        if (Collision.IntersectPixels(bullit.getRect, player1.TextureData, plane.getRect, hunters.TextureData))
                        {
                            //if collision remove projectile and plane
                            plane.hit();
                            bullit.kill();
                            //add score
                            scorePlayer1.Value++;
                        }
                    }

                    if (firstTimeHunter)
                    {
                        // collision plane player
                        if (plane.getRect.Intersects(player1.getRect()))
                        {
                            //if collision remove plane and decrease player power
                            // Shake!
                            rumblePad.RumblePad(PlayerIndex.One, 500, 1.0f, 1.0f);
                            // Player penalty
                            if (!player1.godMode)
                            {
                                player1.Power--;
                                player1.powerUp = 0;
                                player1.Score -= 10;
                            }
                            plane.kill();
                        }

                        #region shooting

                        if (plane.CanShoot)
                        {
                            plane.CanShoot = false;
                            Vector2 tempK = plane.Position;
                            Vector2 tempP = player1.GetPos();

                            if (tempP.Y < tempK.Y)
                            {
                                tempP = tempK - tempP;
                                if (tempP.Y <= tempP.X)
                                {
                                    tempP.X = tempP.X / tempP.Y * -4;
                                    tempP.Y = tempP.Y / tempP.Y * -4;
                                }
                                else
                                {
                                    tempP.Y = tempP.Y / tempP.X * -4;
                                    tempP.X = tempP.X / tempP.X * -4;
                                }
                            }
                            else
                            {
                                tempP = tempK - tempP;
                                if (tempP.Y <= tempP.X)
                                {
                                    tempP.X = tempP.X / tempP.Y * 4;
                                    tempP.Y = tempP.Y / tempP.Y * 4;
                                }
                                else
                                {
                                    tempP.Y = tempP.Y / tempP.X * 4;
                                    tempP.X = tempP.X / tempP.X * 4;
                                }
                            }
                            audio.HunterShoots.Play();
                            projectileMangagerHunter.AddNewProjectile(tempK, tempP, ProjectileType.Hunter);
                        }
                        #endregion
                    }

                }
                firstTimeHunter = false;
                #endregion

                #region Boss

                foreach (Boss plane in bosses.AllBosses)
                {
                    // if plane is not enabled
                    // if plane is exploding
                    // TRUE =  skip collision detection for that item.
                    if (!plane.Enabled || plane.Exploding)
                        continue;

                    // collision proj plane
                    if (bullit.getRect.Intersects(plane.getRect))
                    {
                        plane.hit();
                        //add score
                        scorePlayer1.Value++;
                        bullit.kill();
                    }

                    if (firstTimeBoss)
                    {
                        // collision plane player
                        if (plane.getRect.Intersects(player1.getRect()))
                        {
                            //if collision remove plane and decrease player power
                            // Shake!
                            rumblePad.RumblePad(PlayerIndex.One, 500, 1.0f, 1.0f);
                            // Player penalty
                            if (!player1.godMode)
                            {
                                player1.Power = 0;
                                player1.powerUp = 0;
                                player1.Score -= 10;
                            }
                            plane.kill();
                        }

                        #region shooting
                        if (plane.CanShoot)
                        {
                            plane.CanShoot = false;
                            Vector2 tempK = plane.Position;
                            Vector2 tempP = player1.GetPos();
                            if (tempP.Y < tempK.Y)
                            {
                                tempP = tempK - tempP;
                                if (tempP.Y <= tempP.X)
                                {
                                    tempP.X = tempP.X / tempP.Y * -4;
                                    tempP.Y = tempP.Y / tempP.Y * -4;
                                }
                                else
                                {
                                    tempP.Y = tempP.Y / tempP.X * -4;
                                    tempP.X = tempP.X / tempP.X * -4;
                                }
                            }
                            else
                            {
                                tempP = tempK - tempP;
                                if (tempP.Y <= tempP.X)
                                {
                                    tempP.X = tempP.X / tempP.Y * 4;
                                    tempP.Y = tempP.Y / tempP.Y * 4;
                                }
                                else
                                {
                                    tempP.Y = tempP.Y / tempP.X * 4;
                                    tempP.X = tempP.X / tempP.X * 4;
                                }
                            }

                            projectileMangagerHunter.AddNewProjectile(tempK + bossCorr, tempP, ProjectileType.Hunter);
                            projectileMangagerHunter.AddNewProjectile(tempK + bossCorr, oClock3Player, ProjectileType.Kamakazie);
                            projectileMangagerHunter.AddNewProjectile(tempK + bossCorr, oClock4Player, ProjectileType.Kamakazie);
                            projectileMangagerHunter.AddNewProjectile(tempK + bossCorr, oClock6Player, ProjectileType.Kamakazie);
                            projectileMangagerHunter.AddNewProjectile(tempK + bossCorr, oClock8Player, ProjectileType.Kamakazie);
                            projectileMangagerHunter.AddNewProjectile(tempK + bossCorr, oClock9Player, ProjectileType.Kamakazie);
                        }
                        #endregion
                    }
                }

                firstTimeHunter = false;
                firstTimeKamikaze = false;
                firstTimeBoss = false;
                firstTimeMiner = false;

                #endregion

            }

            #region in no projectiles check other collisions

            if (projList.Count == 0)
            {
                #region kamikaze
                foreach (Kamikaze plane in planeList)
                {
                    // if plane is not enabled
                    // if plane is exploding
                    // TRUE =  skip collision detection for that item.
                    if (!plane.Enabled || plane.Exploding)
                        continue;

                    if (firstTimeKamikaze)
                    {
                        //  collision plane player
                        if (plane.getRect.Intersects(player1.getRect()))
                        {
                            //if collision remove plane and decrease player power

                            // Shake!
                            rumblePad.RumblePad(PlayerIndex.One, 500, 1.0f, 1.0f);
                            // Player penalty
                            if (!player1.godMode)
                            {
                                player1.Power--;
                                player1.powerUp = 0;
                                player1.Score -= 10;
                            }
                            plane.kill();
                        }


                        // shooting
                        if (plane.CanShoot)
                        {
                            plane.CanShoot = false;
                            Vector2 tempK = plane.Position;
                            Vector2 tempP = player1.GetPos();
                            //Checks in player are to right or left of plane
                            if (tempK.X < tempP.X)
                            {
                                currentShot = (tempK.Y < tempP.Y) ? oClock4Kamikaze : oClock2Kamikaze;
                            }
                            else
                            {
                                currentShot = (tempK.Y < tempP.Y) ? oClock8Kamikaze : oClock10Kamikaze;

                            }
                            audio.KamikazeShoots.Play();
                            projectileMangagerKamikaze.AddNewProjectile(tempK, currentShot, ProjectileType.Kamakazie);
                        }
                    }
                }

                firstTimeKamikaze = false;

                #endregion

                #region Miner

                foreach (Miner plane in mineList)
                {
                    // if plane is not enabled
                    // if plane is exploding
                    // TRUE =  skip collision detection for that item.
                    if (!plane.Enabled || plane.Exploding)
                        continue;

                    if (firstTimeMiner)
                    {
                        // collision plane player
                        if (plane.getRect.Intersects(player1.getRect()))
                        {
                            //if collision remove plane and decrease player power
                            // Shake!
                            rumblePad.RumblePad(PlayerIndex.One, 500, 1.0f, 1.0f);
                            // Player penalty
                            if (!player1.godMode)
                            {
                                player1.Power--;
                                player1.powerUp = 0;
                                player1.Score -= 10;
                            }
                            plane.kill();
                        }


                        // lets the plane shoot
                        if (plane.CanShoot)
                        {
                            plane.CanShoot = false;
                            audio.MinerShoots.Play();
                            projectileMangagerKamikaze.AddNewProjectile(plane.Position, mineDirection, ProjectileType.Miner);
                        }
                    }
                }

                firstTimeMiner = false;

                #endregion
                #region Hunter
                foreach (Hunter plane in hunterList)
                {
                    // if plane is not enabled
                    // if plane is exploding
                    // TRUE =  skip collision detection for that item.
                    if (!plane.Enabled || plane.Exploding || !plane.Visible)
                        continue;

                    // collision proj plane
                    if (plane.getRect.Intersects(player1.getRect() ))
                    {
                            plane.hit();
                    }

                    if (firstTimeHunter)
                    {
                        // collision plane player
                        if (plane.getRect.Intersects(player1.getRect()))
                        {
                            //if collision remove plane and decrease player power
                            // Shake!
                            rumblePad.RumblePad(PlayerIndex.One, 500, 1.0f, 1.0f);
                            // Player penalty
                            if (!player1.godMode)
                            {
                                player1.Power--;
                                player1.powerUp = 0;
                                player1.Score -= 10;
                            }
                            plane.kill();
                        }

                        #region shooting

                        if (plane.CanShoot)
                        {
                            plane.CanShoot = false;
                            Vector2 tempK = plane.Position;
                            Vector2 tempP = player1.GetPos();

                            if (tempP.Y < tempK.Y)
                            {
                                tempP = tempK - tempP;
                                if (tempP.Y <= tempP.X)
                                {
                                    tempP.X = tempP.X / tempP.Y * -4;
                                    tempP.Y = tempP.Y / tempP.Y * -4;
                                }
                                else
                                {
                                    tempP.Y = tempP.Y / tempP.X * -4;
                                    tempP.X = tempP.X / tempP.X * -4;
                                }
                            }
                            else
                            {
                                tempP = tempK - tempP;
                                if (tempP.Y <= tempP.X)
                                {
                                    tempP.X = tempP.X / tempP.Y * 4;
                                    tempP.Y = tempP.Y / tempP.Y * 4;
                                }
                                else
                                {
                                    tempP.Y = tempP.Y / tempP.X * 4;
                                    tempP.X = tempP.X / tempP.X * 4;
                                }
                            }
                            audio.HunterShoots.Play();
                            projectileMangagerHunter.AddNewProjectile(tempK, tempP, ProjectileType.Hunter);
                        }
                        #endregion
                    }

                }
                firstTimeHunter = false;
                #endregion

                #region Boss

                foreach (Boss plane in bosses.AllBosses)
                {
                    // if plane is not enabled
                    // if plane is exploding
                    // TRUE =  skip collision detection for that item.
                    if (!plane.Enabled || plane.Exploding)
                        continue;

                    // collision proj plane
                    if (plane.getRect.Intersects(player1.getRect() ))
                    {
                        plane.hit();
                    }

                    if (firstTimeBoss)
                    {
                        // collision plane player
                        if (plane.getRect.Intersects(player1.getRect()))
                        {
                            //if collision remove plane and decrease player power
                            // Shake!
                            rumblePad.RumblePad(PlayerIndex.One, 500, 1.0f, 1.0f);
                            // Player penalty
                            if (!player1.godMode)
                            {
                                player1.Power = 0;
                                player1.powerUp = 0;
                                player1.Score -= 10;
                            }
                            plane.kill();
                        }

                        #region shooting
                        if (plane.CanShoot)
                        {
                            plane.CanShoot = false;
                            Vector2 tempK = plane.Position;
                            Vector2 tempP = player1.GetPos();
                            if (tempP.Y < tempK.Y)
                            {
                                tempP = tempK - tempP;
                                if (tempP.Y <= tempP.X)
                                {
                                    tempP.X = tempP.X / tempP.Y * -4;
                                    tempP.Y = tempP.Y / tempP.Y * -4;
                                }
                                else
                                {
                                    tempP.Y = tempP.Y / tempP.X * -4;
                                    tempP.X = tempP.X / tempP.X * -4;
                                }
                            }
                            else
                            {
                                tempP = tempK - tempP;
                                if (tempP.Y <= tempP.X)
                                {
                                    tempP.X = tempP.X / tempP.Y * 4;
                                    tempP.Y = tempP.Y / tempP.Y * 4;
                                }
                                else
                                {
                                    tempP.Y = tempP.Y / tempP.X * 4;
                                    tempP.X = tempP.X / tempP.X * 4;
                                }
                            }

                            projectileMangagerHunter.AddNewProjectile(tempK + bossCorr, tempP, ProjectileType.Hunter);
                            projectileMangagerHunter.AddNewProjectile(tempK + bossCorr, oClock3Player, ProjectileType.Kamakazie);
                            projectileMangagerHunter.AddNewProjectile(tempK + bossCorr, oClock4Player, ProjectileType.Kamakazie);
                            projectileMangagerHunter.AddNewProjectile(tempK + bossCorr, oClock6Player, ProjectileType.Kamakazie);
                            projectileMangagerHunter.AddNewProjectile(tempK + bossCorr, oClock8Player, ProjectileType.Kamakazie);
                            projectileMangagerHunter.AddNewProjectile(tempK + bossCorr, oClock9Player, ProjectileType.Kamakazie);
                        }
                        #endregion
                    }
                }

                firstTimeHunter = false;
                firstTimeKamikaze = false;
                firstTimeBoss = false;
                firstTimeMiner = false;

                #endregion

            }
            #endregion
        }

        /// <summary>
        /// Checks Collision between enemy projectiles and player
        /// </summary>
        private void checkCol(List<Projectile> projList, Rectangle playerRect, ProjectileType projType)
        {
            foreach (Projectile proj in projList)
            {
                // if plane is not enabled
                // TRUE =  skip collision detection for that item.
                if (!proj.Enabled)
                    continue;

                if (proj.getRect.Intersects(playerRect))
                {
                    if (Collision.IntersectPixels(proj.getRect, kamikazes.TextureData, playerRect, player1.TextureData))
                    {
                        //if collision remove projectile and decrease player power
                        proj.kill();
                        player1.Power--;

                        // If mine-hit, loss one extra power
                        if (projType == ProjectileType.Miner)
                            player1.Power--;

                        player1.powerUp--;

                    }
                }

            }
        }
        #endregion

        /// <summary>
        /// Allows the game component to draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Draw(GameTime gameTime)
        {
            // Draw the moving background
            spriteBatch.Draw(backTexture, backgroundPos, backgroundRect, Color.White);

            //Level 2 of Clouds
            spriteBatch.Draw(backCloudTexture, backgroundCloudPosLvl2, backgroundCloudRect, Color.White);
            spriteBatch.Draw(backCloudTexture, backgroundCloud2PosLvl2, backgroundCloudRect, Color.White);

            // Draw the moving background Clouds
            spriteBatch.Draw(backCloudTexture, backgroundCloudPos, backgroundCloudRect, Color.White);
            spriteBatch.Draw(backCloudTexture, backgroundCloud2Pos, backgroundCloudRect, Color.White);

            

            // Draw all game components
            base.Draw(gameTime);

            if (paused)
            {
                // Draw the "pause" text
                spriteBatch.Draw(actionTexture, pausePosition, pauseRect, Color.White);
            }

            if (gameOver)
            {
                // Draw the "gameover" text
                spriteBatch.Draw(actionTexture, gameoverPosition, gameoverRect, Color.White);
            }

            if (stageClear)
            {
                // Draw the "gameover" text
                spriteBatch.Draw(actionTexture, stageClearPosition, stageClearRect, Color.White);
            }
        }

        #endregion

#region Properties
        /// <summary>
        /// True, if the game is in GameOver state
        /// </summary>
        public bool GameOver
        {
            get { return gameOver; }
        }

        /// <summary>
        /// True, if the game is in stageClear state
        /// </summary>
        public bool StageClear
        {
            get { return stageClear; }
        }

        /// <summary>
        /// Paused mode
        /// </summary>
        public bool Paused
        {
            get { return paused; }
            set
            {
                paused = value;
                if (paused)
                {
                    MediaPlayer.Pause();
                }
                else
                {
                    MediaPlayer.Resume();
                }
            }
        }

#endregion


    }
}